namespace Org.Loon.Framework.Xna.Game.Core.Geom {

    using System;
    using System.Collections.Generic;
    using Org.Loon.Framework.Xna.Game.Utils.ILog;

	public sealed class Matrix {
	
		public class Transform2D {
	
			private readonly float[] temp_vertives;
	
			private float m01;
	
			private float m02;
	
			private float m03;
	
			private float m04;
	
			private float tx;
	
			private float ty;
	
			public Transform2D() {
				this.temp_vertives = new float[8];
				this.m01 = 1.0f;
				this.m02 = 0.0f;
				this.m03 = 0.0f;
				this.m04 = 1.0f;
				this.tx = 0.0f;
				this.ty = 0.0f;
	
			}
	
			public void Reset() {
				this.SetToIdentity();
			}
	
			public void SetToIdentity() {
				this.m01 = 1.0f;
				this.m04 = 1.0f;
				this.m02 = 0.0f;
				this.m03 = 0.0f;
				this.tx = 0.0f;
				this.ty = 0.0f;
			}
	
			public void SetTo(Matrix.Transform2D  t) {
				this.m01 = t.m01;
				this.m04 = t.m04;
				this.m02 = t.m02;
				this.m03 = t.m03;
				this.tx = t.tx;
				this.ty = t.ty;
			}
	
			public void PreTranslate(float tx_0, float ty_1) {
				this.tx += tx_0 * this.m01 + ty_1 * this.m03;
				this.ty += tx_0 * this.m02 + ty_1 * this.m04;
			}
	
			public void PostTranslate(float tx_0, float ty_1) {
				this.tx += tx_0;
				this.ty += ty_1;
			}
	
			public Matrix.Transform2D  SetToTranslate(float tx_0, float ty_1) {
				this.m01 = 1.0f;
				this.m02 = 0.0f;
				this.m03 = 0.0f;
				this.m04 = 1.0f;
				this.tx = tx_0;
				this.ty = ty_1;
				return this;
			}
	
			public void PreScale(float sx, float sy) {
				this.m01 *= sx;
				this.m02 *= sx;
				this.m03 *= sy;
				this.m04 *= sy;
			}
	
			public void PostScale(float sx, float sy) {
				this.m01 = this.m01 * sx;
				this.m02 = this.m02 * sy;
				this.m03 = this.m03 * sx;
				this.m04 = this.m04 * sy;
				this.tx = this.tx * sx;
				this.ty = this.ty * sy;
			}
	
			public Matrix.Transform2D  SetToScale(float sx, float sy) {
				this.m01 = sx;
				this.m02 = 0.0f;
				this.m03 = 0.0f;
				this.m04 = sy;
				this.tx = 0.0f;
				this.ty = 0.0f;
				return this;
			}
	
			public void PreRotate(float rotation) {
				float angleRad = Org.Loon.Framework.Xna.Game.Utils.MathUtils.ToRadians(rotation);
				float sin = Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angleRad);
				float cos = Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angleRad);
				float m01_0 = this.m01;
				float m02_1 = this.m02;
				float m03_2 = this.m03;
				float m04_3 = this.m04;
				this.m01 = cos * m01_0 + sin * m03_2;
				this.m02 = cos * m02_1 + sin * m04_3;
				this.m03 = cos * m03_2 - sin * m01_0;
				this.m04 = cos * m04_3 - sin * m02_1;
			}
	
			public void PostRotate(float rotation) {
				float angleRad = Org.Loon.Framework.Xna.Game.Utils.MathUtils.ToRadians(rotation);
				float sin = Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angleRad);
				float cos = Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angleRad);
				float m01_0 = this.m01;
				float m02_1 = this.m02;
				float m03_2 = this.m03;
				float m04_3 = this.m04;
				float tx_4 = this.tx;
				float ty_5 = this.ty;
				this.m01 = m01_0 * cos - m02_1 * sin;
				this.m02 = m01_0 * sin + m02_1 * cos;
				this.m03 = m03_2 * cos - m04_3 * sin;
				this.m04 = m03_2 * sin + m04_3 * cos;
				this.tx = tx_4 * cos - ty_5 * sin;
				this.ty = tx_4 * sin + ty_5 * cos;
			}
	
			public Matrix.Transform2D  SetToRotate(float rotation) {
				float angleRad = Org.Loon.Framework.Xna.Game.Utils.MathUtils.ToRadians(rotation);
				float sin = Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angleRad);
				float cos = Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angleRad);
				this.m01 = cos;
				this.m02 = sin;
				this.m03 = -sin;
				this.m04 = cos;
				this.tx = 0.0f;
				this.ty = 0.0f;
				return this;
			}
	
			public void PostConcat(Matrix.Transform2D  t) {
				this.PostConcat(t.m01, t.m02, t.m03, t.m04, t.tx, t.ty);
			}
	
			public void PostConcat(float x1, float y1, float x2,
					float y2, float x3, float y3) {
				float m01_0 = this.m01;
				float m02_1 = this.m02;
				float m03_2 = this.m03;
				float m04_3 = this.m04;
				float tx_4 = this.tx;
				float ty_5 = this.ty;
				this.m01 = m01_0 * x1 + m02_1 * x2;
				this.m02 = m01_0 * y1 + m02_1 * y2;
				this.m03 = m03_2 * x1 + m04_3 * x2;
				this.m04 = m03_2 * y1 + m04_3 * y2;
				this.tx = tx_4 * x1 + ty_5 * x2 + x3;
				this.ty = tx_4 * y1 + ty_5 * y2 + y3;
			}
	
			public void PreConcat(Matrix.Transform2D  t) {
				this.PreConcat(t.m01, t.m02, t.m03, t.m04, t.tx, t.ty);
			}
	
			public void PreConcat(float x1, float y1, float x2,
					float y2, float x3, float y3) {
				float m01_0 = this.m01;
				float m02_1 = this.m02;
				float m03_2 = this.m03;
				float m04_3 = this.m04;
				float tx_4 = this.tx;
				float ty_5 = this.ty;
				this.m01 = x1 * m01_0 + y1 * m03_2;
				this.m02 = x1 * m02_1 + y1 * m04_3;
				this.m03 = x2 * m01_0 + y2 * m03_2;
				this.m04 = x2 * m02_1 + y2 * m04_3;
				this.tx = x3 * m01_0 + y3 * m03_2 + tx_4;
				this.ty = x3 * m02_1 + y3 * m04_3 + ty_5;
			}
	
			public float[] Transform(float x1, float y1, float x2, float y2,
					float x3, float y3, float x4, float y4) {
				temp_vertives[0] = x1;
				temp_vertives[1] = y1;
				temp_vertives[2] = x2;
				temp_vertives[3] = y2;
				temp_vertives[4] = x3;
				temp_vertives[5] = y3;
				temp_vertives[6] = x4;
				temp_vertives[7] = y4;
				Transform(temp_vertives);
				return temp_vertives;
			}
	
			public void Transform(float[] vers) {
				int count = vers.Length >> 1;
				int i = 0;
				int j = 0;
				for (; --count >= 0;) {
					float x = vers[i++];
					float y = vers[i++];
					vers[j++] = x * this.m01 + y * this.m03 + this.tx;
					vers[j++] = x * this.m02 + y * this.m04 + this.ty;
				}
			}
		}
	
		public class Transform2i {
	
			public Transform2i() {
				this.matrixs = Empty();
			}
	
			public int[][] matrixs;
	
			public void Idt() {
				this.matrixs = Empty();
			}
	
			public int Get(int x, int y) {
				return matrixs[x][y];
			}
	
			public void Set(int[][] matrixs_0) {
				this.matrixs = matrixs_0;
			}
	
			public void Mul(int[][] matrixs_0) {
				this.matrixs = Mul(matrixs_0, matrixs_0);
			}
	
			public int[] Mul(int[] fpV) {
				return Mul(matrixs, fpV);
			}
	
			public void Rotate(float alpha, float x, float y) {
				if (alpha != 1f) {
					int[][] angle = RotationMatrix(alpha, x, y);
					this.matrixs = Mul(matrixs, angle);
				}
			}
	
			public void Zoom(float scale, float x, float y) {
				if (scale != 1f) {
					int[][] zoom = ZoomMatrix(scale, x, y);
					this.matrixs = Mul(matrixs, zoom);
				}
			}
	
			public static int[][] Empty() {
				int[][] id = {
						new int[] {
								Org.Loon.Framework.Xna.Game.Utils.MathUtils.ONE_FIXED,
								0, 0 },
						new int[] {
								0,
								Org.Loon.Framework.Xna.Game.Utils.MathUtils.ONE_FIXED,
								0 },
						new int[] {
								0,
								0,
								Org.Loon.Framework.Xna.Game.Utils.MathUtils.ONE_FIXED } };
				return id;
			}
	
			public static int[][] Def() {
				int[][] id = { new int[] { 0, 0, 0 }, new int[] { 0, 0, 0 },
						new int[] { 0, 0, 0 } };
				return id;
			}
	
			public static int[][] Mul(int[][] a, int[][] b) {
				int[][] matrixs_0 = Def();
				for (int i = 0; i < 3; ++i) {
					for (int j = 0; j < 3; ++j) {
						for (int n = 0; n < 3; ++n) {
							matrixs_0[i][j] += Org.Loon.Framework.Xna.Game.Utils.MathUtils.Mul(a[i][n], b[n][j]);
						}
					}
				}
				return matrixs_0;
			}
	
			public static int[] Mul(int[][] a, int[] b) {
				int[] matrixs_0 = { 0, 0, 0 };
				for (int i = 0; i < 3; ++i) {
					for (int j = 0; j < 3; ++j) {
						matrixs_0[i] += Org.Loon.Framework.Xna.Game.Utils.MathUtils.Mul(a[i][j], b[j]);
					}
				}
				return matrixs_0;
			}
	
			public static int[][] ZoomMatrix(float scale,
					float x, float y) {
				int mu = (0 == scale) ? Int32.MaxValue : Org.Loon.Framework.Xna.Game.Utils.MathUtils
						.FromFloat(1 / scale);
				if (Org.Loon.Framework.Xna.Game.Utils.MathUtils.ONE_FIXED == mu) {
					return Def();
				}
				int x_c = Org.Loon.Framework.Xna.Game.Utils.MathUtils.FromFloat(x);
				int y_c = Org.Loon.Framework.Xna.Game.Utils.MathUtils.FromFloat(y);
				int transX = x_c - Org.Loon.Framework.Xna.Game.Utils.MathUtils.Mul(x_c, mu);
				int transY = y_c - Org.Loon.Framework.Xna.Game.Utils.MathUtils.Mul(y_c, mu);
				int[][] zoom = {
						new int[] { mu, 0, transX },
						new int[] { 0, mu, transY },
						new int[] {
								0,
								0,
								Org.Loon.Framework.Xna.Game.Utils.MathUtils.ONE_FIXED } };
				return zoom;
			}
	
			public static int[][] RotationMatrix(float alpha,
					float x, float y) {
				if (0 == alpha % (2 * Org.Loon.Framework.Xna.Game.Utils.MathUtils.PI)) {
					return Empty();
				}
				int cosAlpha = Org.Loon.Framework.Xna.Game.Utils.MathUtils.FromDouble(Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(alpha));
				int sinAlpha = Org.Loon.Framework.Xna.Game.Utils.MathUtils.FromDouble(Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(alpha));
				int x_c = Org.Loon.Framework.Xna.Game.Utils.MathUtils.FromFloat(x);
				int y_c = Org.Loon.Framework.Xna.Game.Utils.MathUtils.FromFloat(y);
				int transX = Org.Loon.Framework.Xna.Game.Utils.MathUtils.Mul(x_c, Org.Loon.Framework.Xna.Game.Utils.MathUtils.ONE_FIXED
						- cosAlpha)
						+ Org.Loon.Framework.Xna.Game.Utils.MathUtils.Mul(y_c, sinAlpha);
				int transY = Org.Loon.Framework.Xna.Game.Utils.MathUtils.Mul(y_c, Org.Loon.Framework.Xna.Game.Utils.MathUtils.ONE_FIXED
						- cosAlpha)
						- Org.Loon.Framework.Xna.Game.Utils.MathUtils.Mul(x_c, sinAlpha);
				int[][] angle = {
						new int[] { cosAlpha, -sinAlpha, transX },
						new int[] { sinAlpha, cosAlpha, transY },
						new int[] {
								0,
								0,
								Org.Loon.Framework.Xna.Game.Utils.MathUtils.ONE_FIXED } };
				return angle;
			}
	
		}
	
		private float[] matrixs;
	
		public Matrix() {
			this.Idt();
		}
	
		public Matrix(Matrix m) {
			matrixs = new float[9];
			for (int i = 0; i < 9; i++) {
				matrixs[i] = m.matrixs[i];
			}
		}
	
		public Matrix(Matrix t1, Matrix t2):	this(t1) {
		
			Concatenate(t2);
		}
	
		public Matrix(float[] matrixs_0) {
			if (matrixs_0.Length != 9) {
				throw new Exception("matrixs.length != 9");
			}
			this.matrixs = new float[] { matrixs_0[0], matrixs_0[1], matrixs_0[2],
					matrixs_0[3], matrixs_0[4], matrixs_0[5], matrixs_0[6], matrixs_0[7],
					matrixs_0[8] };
		}
	
		public void Set(float x1, float y1, float x2, float y2) {
			Set(x1, y1, 1, x2, y2, 1);
		}
	
		public Matrix(float a1, float a2, float a3, float b1, float b2, float b3) {
			Set(a1, a2, a3, b1, b2, b3);
		}
	
		public void Set(float a1, float a2, float a3, float b1, float b2, float b3) {
			Set(a1, a2, a3, b1, b2, b3, 0, 0, 1);
		}
	
		public void Set(float a1, float a2, float a3, float b1, float b2, float b3,
				float c1, float c2, float c3) {
			matrixs = new float[] { a1, a2, a3, b1, b2, b3, c1, c2, c3 };
		}
	
		public void Transform(float[] source, int sourceOffset,
				float[] destination, int destOffset, int numberOfPoints) {
	
			float[] result = (source == destination) ? new float[numberOfPoints * 2]
					: destination;
	
			for (int i = 0; i < numberOfPoints * 2; i += 2) {
				for (int j = 0; j < 6; j += 3) {
					result[i + (j / 3)] = source[i + sourceOffset] * matrixs[j]
							+ source[i + sourceOffset + 1] * matrixs[j + 1] + 1
							* matrixs[j + 2];
				}
			}
	
			if (source == destination) {
				for (int i_0 = 0; i_0 < numberOfPoints * 2; i_0 += 2) {
					destination[i_0 + destOffset] = result[i_0];
					destination[i_0 + destOffset + 1] = result[i_0 + 1];
				}
			}
		}
	
		public Matrix Concatenate(Matrix m) {
			float[] mp = new float[9];
			float n00 = matrixs[0] * m.matrixs[0] + matrixs[1] * m.matrixs[3];
			float n01 = matrixs[0] * m.matrixs[1] + matrixs[1] * m.matrixs[4];
			float n02 = matrixs[0] * m.matrixs[2] + matrixs[1] * m.matrixs[5]
					+ matrixs[2];
			float n10 = matrixs[3] * m.matrixs[0] + matrixs[4] * m.matrixs[3];
			float n11 = matrixs[3] * m.matrixs[1] + matrixs[4] * m.matrixs[4];
			float n12 = matrixs[3] * m.matrixs[2] + matrixs[4] * m.matrixs[5]
					+ matrixs[5];
			mp[0] = n00;
			mp[1] = n01;
			mp[2] = n02;
			mp[3] = n10;
			mp[4] = n11;
			mp[5] = n12;
	
			matrixs = mp;
			return this;
		}
	
		public static Matrix CreateRotateTransform(float angle) {
			return new Matrix(Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angle), -Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angle), 0,
					Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angle), Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angle), 0);
		}
	
		public static Matrix CreateRotateTransform(float angle, float x, float y) {
			Matrix temp = Matrix.CreateRotateTransform(angle);
			float sinAngle = temp.matrixs[3];
			float oneMinusCosAngle = 1.0f - temp.matrixs[4];
			temp.matrixs[2] = x * oneMinusCosAngle + y * sinAngle;
			temp.matrixs[5] = y * oneMinusCosAngle - x * sinAngle;
			return temp;
		}
	
		public static Matrix CreateTranslateTransform(float xOffset, float yOffset) {
			return new Matrix(1, 0, xOffset, 0, 1, yOffset);
		}
	
		public static Matrix CreateScaleTransform(float scalex, float scaley) {
			return new Matrix(scalex, 0, 0, 0, scaley, 0);
		}
	
		public float Get(int x, int y) {
			try {
				return matrixs[x * 3 + y];
			} catch (Exception ex) {
                Log.Exception(ex);
				throw new ArgumentException("Invalid indices into matrix !");
			}
		}
	
		public void Set(int x, int y, float v) {
			try {
				this.matrixs[x * 3 + y] = v;
			} catch (Exception ex) {
                Log.Exception(ex);
				throw new ArgumentException("Invalid indices into matrix !");
			}
		}
	
		public Matrix Set(Matrix m) {
			matrixs[0] = m.matrixs[0];
			matrixs[1] = m.matrixs[1];
			matrixs[2] = m.matrixs[2];
			matrixs[3] = m.matrixs[3];
			matrixs[4] = m.matrixs[4];
			matrixs[5] = m.matrixs[5];
			matrixs[6] = m.matrixs[6];
			matrixs[7] = m.matrixs[7];
			matrixs[8] = m.matrixs[8];
			return this;
		}
	
		public Matrix From(float[] source, bool rowMajor) {
			Matrix m = new Matrix();
			if (rowMajor) {
				for (int i = 0; i < 3; i++) {
					for (int j = 0; j < 3; j++) {
						m.Set(i, j, source[i * 3 + j]);
					}
				}
			} else {
				for (int j_0 = 0; j_0 < 3; j_0++) {
					for (int i_1 = 0; i_1 < 3; i_1++) {
						m.Set(i_1, j_0, source[j_0 * 3 + i_1]);
					}
				}
			}
			return this;
		}
	
		public void Translation(float x, float y) {
			this.matrixs[0] = 1;
			this.matrixs[1] = 0;
			this.matrixs[2] = 0;
			this.matrixs[3] = 0;
			this.matrixs[4] = 1;
			this.matrixs[5] = 0;
			this.matrixs[6] = x;
			this.matrixs[7] = y;
			this.matrixs[8] = 1;
		}
	
		public void Rotation(float angle) {
			angle = Org.Loon.Framework.Xna.Game.Utils.MathUtils.PI / 180 * angle;
			float cos = Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angle);
			float sin = Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angle);
			this.matrixs[0] = cos;
			this.matrixs[1] = sin;
			this.matrixs[2] = 0;
			this.matrixs[3] = -sin;
			this.matrixs[4] = cos;
			this.matrixs[5] = 0;
			this.matrixs[6] = 0;
			this.matrixs[7] = 0;
			this.matrixs[8] = 1;
		}
	
		public void RotationX(float angleX) {
			angleX = Org.Loon.Framework.Xna.Game.Utils.MathUtils.PI / 180 * angleX;
			Set(1f, 0f, 0f, 0f, Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angleX), -Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angleX), 0f,
					Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angleX), Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angleX));
		}
	
		public void RotationY(float angleY) {
			angleY = Org.Loon.Framework.Xna.Game.Utils.MathUtils.PI / 180 * angleY;
			Set(Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angleY), 0f, Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angleY), 0f, 1f, 0f,
					-Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angleY), 0f, Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angleY));
		}
	
		public void RotationZ(float angleZ) {
			angleZ = Org.Loon.Framework.Xna.Game.Utils.MathUtils.PI / 180 * angleZ;
			Set(Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angleZ), -Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angleZ), 0f,
					Org.Loon.Framework.Xna.Game.Utils.MathUtils.Sin(angleZ), Org.Loon.Framework.Xna.Game.Utils.MathUtils.Cos(angleZ), 0f, 0f, 0f, 1f);
		}
	
		public void Scale(float sx, float sy) {
			this.matrixs[0] = sx;
			this.matrixs[1] = 0;
			this.matrixs[2] = 0;
			this.matrixs[3] = 0;
			this.matrixs[4] = sy;
			this.matrixs[5] = 0;
			this.matrixs[6] = 0;
			this.matrixs[7] = 0;
			this.matrixs[8] = 1;
		}
	
		public void Idt() {
			if (matrixs == null) {
				matrixs = new float[] { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
			} else {
				this.matrixs[0] = 1;
				this.matrixs[1] = 0;
				this.matrixs[2] = 0;
				this.matrixs[3] = 0;
				this.matrixs[4] = 1;
				this.matrixs[5] = 0;
				this.matrixs[6] = 0;
				this.matrixs[7] = 0;
				this.matrixs[8] = 1;
			}
		}
	
		public bool IsIdt() {
			return (matrixs[0] == 1 && matrixs[1] == 0 && matrixs[2] == 0)
					&& (matrixs[3] == 0 && matrixs[4] == 1 && matrixs[5] == 0)
					&& (matrixs[6] == 0 && matrixs[7] == 0 && matrixs[8] == 1);
		}
	
		public float Det() {
			return matrixs[0] * matrixs[4] * matrixs[8] + matrixs[3] * matrixs[7]
					* matrixs[2] + matrixs[6] * matrixs[1] * matrixs[5]
					- matrixs[0] * matrixs[7] * matrixs[5] - matrixs[3]
					* matrixs[1] * matrixs[8] - matrixs[6] * matrixs[4]
					* matrixs[2];
		}
	
		private static float Detd(float a, float b, float c, float d) {
			return (a * d) - (b * c);
		}
	
		public void Adj() {
	
			float a11 = this.matrixs[0];
			float a12 = this.matrixs[1];
			float a13 = this.matrixs[2];
	
			float a21 = this.matrixs[3];
			float a22 = this.matrixs[4];
			float a23 = this.matrixs[5];
	
			float a31 = this.matrixs[6];
			float a32 = this.matrixs[7];
			float a33 = this.matrixs[8];
	
			this.matrixs[0] = Detd(a22, a23, a32, a33);
			this.matrixs[1] = Detd(a13, a12, a33, a32);
			this.matrixs[2] = Detd(a12, a13, a22, a23);
	
			this.matrixs[3] = Detd(a23, a21, a33, a31);
			this.matrixs[4] = Detd(a11, a13, a31, a33);
			this.matrixs[5] = Detd(a13, a11, a23, a21);
	
			this.matrixs[6] = Detd(a21, a22, a31, a32);
			this.matrixs[7] = Detd(a12, a11, a32, a31);
			this.matrixs[8] = Detd(a11, a12, a21, a22);
		}
	
		public void Add(Matrix m) {
			float a1 = this.matrixs[0];
			float a2 = this.matrixs[1];
			float a3 = this.matrixs[2];
	
			float b1 = this.matrixs[3];
			float b2 = this.matrixs[4];
			float b3 = this.matrixs[5];
	
			float c1 = this.matrixs[6];
			float c2 = this.matrixs[7];
			float c3 = this.matrixs[8];
	
			a1 += m.matrixs[0];
			a2 += m.matrixs[1];
			a3 += m.matrixs[2];
	
			b1 += m.matrixs[3];
			b2 += m.matrixs[4];
			b3 += m.matrixs[5];
	
			c1 += m.matrixs[6];
			c2 += m.matrixs[7];
			c3 += m.matrixs[8];
	
			this.matrixs[0] = a1;
			this.matrixs[1] = a2;
			this.matrixs[2] = a3;
			this.matrixs[3] = b1;
			this.matrixs[4] = b2;
			this.matrixs[5] = b3;
			this.matrixs[6] = c1;
			this.matrixs[7] = c2;
			this.matrixs[8] = c3;
		}
	
		public Matrix AddEqual(Matrix m) {
			Matrix newMatrix = new Matrix(this.matrixs);
			newMatrix.Add(m);
			return newMatrix;
		}
	
		public void Mul(float c) {
			float a1 = this.matrixs[0];
			float a2 = this.matrixs[1];
			float a3 = this.matrixs[2];
	
			float b1 = this.matrixs[3];
			float b2 = this.matrixs[4];
			float b3 = this.matrixs[5];
	
			float c1 = this.matrixs[6];
			float c2 = this.matrixs[7];
			float c3 = this.matrixs[8];
	
			this.matrixs[0] = a1 * c;
			this.matrixs[1] = a2 * c;
			this.matrixs[2] = a3 * c;
			this.matrixs[3] = b1 * c;
			this.matrixs[4] = b2 * c;
			this.matrixs[5] = b3 * c;
			this.matrixs[6] = c1 * c;
			this.matrixs[7] = c2 * c;
			this.matrixs[8] = c3 * c;
		}
	
		public void Mul(Matrix m) {
			float a1 = matrixs[0] * m.matrixs[0] + matrixs[3] * m.matrixs[1]
					+ matrixs[6] * m.matrixs[2];
			float a2 = matrixs[0] * m.matrixs[3] + matrixs[3] * m.matrixs[4]
					+ matrixs[6] * m.matrixs[5];
			float a3 = matrixs[0] * m.matrixs[6] + matrixs[3] * m.matrixs[7]
					+ matrixs[6] * m.matrixs[8];
	
			float b1 = matrixs[1] * m.matrixs[0] + matrixs[4] * m.matrixs[1]
					+ matrixs[7] * m.matrixs[2];
			float b2 = matrixs[1] * m.matrixs[3] + matrixs[4] * m.matrixs[4]
					+ matrixs[7] * m.matrixs[5];
			float b3 = matrixs[1] * m.matrixs[6] + matrixs[4] * m.matrixs[7]
					+ matrixs[7] * m.matrixs[8];
	
			float c1 = matrixs[2] * m.matrixs[0] + matrixs[5] * m.matrixs[1]
					+ matrixs[8] * m.matrixs[2];
			float c2 = matrixs[2] * m.matrixs[3] + matrixs[5] * m.matrixs[4]
					+ matrixs[8] * m.matrixs[5];
			float c3 = matrixs[2] * m.matrixs[6] + matrixs[5] * m.matrixs[7]
					+ matrixs[8] * m.matrixs[8];
	
			this.matrixs[0] = a1;
			this.matrixs[1] = a2;
			this.matrixs[2] = a3;
	
			this.matrixs[3] = b1;
			this.matrixs[4] = b2;
			this.matrixs[5] = b3;
	
			this.matrixs[6] = c1;
			this.matrixs[7] = c2;
			this.matrixs[8] = c3;
	
		}
	
		public Matrix MulEqual(Matrix m) {
			if (m == null) {
				m = new Matrix();
			}
			Matrix result = new Matrix(this.matrixs);
			result.Mul(m);
			return result;
		}
	
		public Matrix Invert(Matrix m) {
			Matrix result = m;
			if (result == null) {
				result = new Matrix();
			}
	
			float det = Det();
			if (Math.Abs(det) <= Org.Loon.Framework.Xna.Game.Utils.MathUtils.EPSILON) {
				throw new ArithmeticException("This matrix cannot be inverted !");
			}
	
			float temp00 = matrixs[4] * matrixs[8] - matrixs[5] * matrixs[7];
			float temp01 = matrixs[2] * matrixs[7] - matrixs[1] * matrixs[8];
			float temp02 = matrixs[1] * matrixs[5] - matrixs[2] * matrixs[4];
			float temp10 = matrixs[5] * matrixs[6] - matrixs[3] * matrixs[8];
			float temp11 = matrixs[0] * matrixs[8] - matrixs[2] * matrixs[6];
			float temp12 = matrixs[2] * matrixs[3] - matrixs[0] * matrixs[5];
			float temp20 = matrixs[3] * matrixs[7] - matrixs[4] * matrixs[6];
			float temp21 = matrixs[1] * matrixs[6] - matrixs[0] * matrixs[7];
			float temp22 = matrixs[0] * matrixs[4] - matrixs[1] * matrixs[3];
			result.Set(temp00, temp01, temp02, temp10, temp11, temp12, temp20,
					temp21, temp22);
			result.Mul(1.0f / det);
			return result;
		}
	
		public bool IsFloatValid() {
	
			bool valid = true;
	
			valid &= !Single.IsNaN(matrixs[0]);
			valid &= !Single.IsNaN(matrixs[1]);
			valid &= !Single.IsNaN(matrixs[2]);
	
			valid &= !Single.IsNaN(matrixs[3]);
			valid &= !Single.IsNaN(matrixs[4]);
			valid &= !Single.IsNaN(matrixs[5]);
	
			valid &= !Single.IsNaN(matrixs[6]);
			valid &= !Single.IsNaN(matrixs[7]);
			valid &= !Single.IsNaN(matrixs[8]);
	
			return valid;
		}
	
		public static Matrix Avg(ICollection<Matrix> set) {
			Matrix average = new Matrix();
			average.Set(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f);
			float hist = 0;
			foreach (Matrix matrix3d  in  set) {
				if (matrix3d.IsFloatValid()) {
					average.Add(matrix3d);
					hist++;
				}
			}
			average.Mul(1f / hist);
			return average;
		}
	
		public void Copy(Matrix m) {
			if (m == null) {
				Idt();
			} else {
				Set(m);
			}
		}
	
		public override bool Equals(Object o) {
			if (!(o  is  Matrix) || o == null) {
				return false;
			}
	
			if ((Object) this == o) {
				return true;
			}
	
			Matrix comp = (Matrix) o;
	
			if (matrixs[0].CompareTo(comp.matrixs[0]) != 0) {
				return false;
			}
			if (matrixs[1].CompareTo(comp.matrixs[1]) != 0) {
				return false;
			}
			if (matrixs[2].CompareTo(comp.matrixs[2]) != 0) {
				return false;
			}
	
			if (matrixs[3].CompareTo(comp.matrixs[3]) != 0) {
				return false;
			}
			if (matrixs[4].CompareTo(comp.matrixs[4]) != 0) {
				return false;
			}
			if (matrixs[5].CompareTo(comp.matrixs[5]) != 0) {
				return false;
			}
	
			if (matrixs[6].CompareTo(comp.matrixs[6]) != 0) {
				return false;
			}
			if (matrixs[7].CompareTo(comp.matrixs[7]) != 0) {
				return false;
			}
			if (matrixs[8].CompareTo(comp.matrixs[8]) != 0) {
				return false;
			}
	
			return true;
		}
	
		public override int GetHashCode() {
			int result = 17;
			for (int j = 0; j < 9; j++) {
				long val = (long)matrixs[j];
				result += 31 * result + (int) (val ^ ((long) (((ulong) val) >> 32)));
			}
			return result;
		}
	
		public Vector2f Transform(Vector2f pt) {
			float[] ins0 = new float[] { pt.x, pt.y };
			float[] xout = new float[2];
	
			Transform(ins0, 0, xout, 0, 1);
	
			return new Vector2f(xout[0], xout[1]);
		}
	
		public Matrix Clone() {
			return new Matrix(this.matrixs);
		}
	
		public float[] GetValues() {
			return matrixs;
		}
	}
}
